home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
10,000 Great Games
/
10,000 Great Games.iso
/
Product
/
66
/
data1.cab
/
Source_Files
/
Src
/
MakeRandom.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2000-01-16
|
6KB
|
273 lines
#include "stdafx.h"
#define MAX_TRIES 30
class cOccupied : public cBox
{
public:
cOccupied(cOccupied **list, int x1, int y1, int x2, int y2, cProperties *p);
static int jumpable(int x, int y, cProperties *p);
static int occupy(int x, int y, cProperties *p);
cProperties *what;
};
static cOccupied *game_occ = 0, *back_occ = 0;
cOccupied::cOccupied(cOccupied **list, int _x1, int _y1, int _x2, int _y2, cProperties *p)
{
add((cList **)list);
x1 = _x1, y1 = _y1, x2 = _x2, y2 = _y2;
what = p;
}
int cOccupied::jumpable(int x, int y, cProperties *p)
{
ASSERT (p->objtype != 0);
// Get list to check with
cOccupied *list = *p->objtype->surface == game_surface? game_occ : back_occ;
// Force jumpable when list is empty
if (list == 0)
return TRUE;
// Get coordinates of bounding box
int x1 = x + p->bbox.x1,
y1 = y - p->bbox.y1,
x2 = x + p->bbox.x2;
// Check if any other platform is jumpable from this platform
for (cOccupied *o = list; o != 0; o = (cOccupied *)o->next)
{
if (y1 == o->y1 && o->x1 - x2 <= LEVEL_HJUMP && x1 - o->x2 <= LEVEL_HJUMP)
return TRUE;
if (abs(y1 - o->y1) <= LEVEL_VJUMP && o->x1 - x2 <= LEVEL_HJUMP / 2 && x1 - o->x2 <= LEVEL_HJUMP / 2)
return TRUE;
}
// None found
return FALSE;
}
int cOccupied::occupy(int x, int y, cProperties *p)
{
ASSERT (p->objtype != 0);
cOccupied **list = *p->objtype->surface == game_surface? &game_occ : &back_occ;
int x1 = x + p->bbox.x1,
y1 = y - p->bbox.y1,
x2 = x + p->bbox.x2,
y2 = y - p->bbox.y2;
// If not forced to occupy check if there is another object in the list
// occupying the same space
if (p->no_overlap)
for (cOccupied *o = *list; o != 0; o = (cOccupied *)o->next)
if (x1 < o->x2 && o->x1 < x2 && y2 < o->y1 && o->y2 < y1)
return FALSE;
// Add to list
new cOccupied(list, x1, y1, x2, y2, p);
// Create real object
cObjectTypes::make(x, y, p, TRUE);
return TRUE;
}
static int determine_number(int r)
{
// This is assumed now
ASSERT (r >= 0 && r <= 300);
// Return number of things to create on this level
if (r < 100)
return rnd(100) < r? 1 : 0;
else
return (3 * r / 4 + rnd(r / 2) + 50) / 100;
}
static void make_platforms()
{
// Create random list
cRandomList platforms(PLACEMENT_PLATFORM);
if (platforms.is_empty() || random_placement_platform <= 0)
{
info("Warning: No platforms created!");
return;
}
// Variable to indicate impossible jump
int jumpable_warning = FALSE;
// Loop through all levels
for (int l = LEVEL_VJUMP; l < LEVEL_SIZE; l += LEVEL_VJUMP)
{
// Determine number of platforms to add
int n = determine_number(random_placement_platform);
// Case no platforms on this level
if (n <= 0)
{
if (random_placement_platform >= 100)
n = 1;
else
jumpable_warning = TRUE;
}
// Create platforms
while (n > 0)
{
// Get random object
cProperties *p = platforms.get_weighted_random();
// Try to add this platform
for (int tries = 0; tries < 2 * MAX_TRIES; tries++)
{
int x = -p->bbox.x1 + GAME_EDGE + rnd(GAME_DX - 2 * GAME_EDGE - (p->bbox.x2 - p->bbox.x1)),
y = l + p->bbox.y1;
if ((tries >= MAX_TRIES || cOccupied::jumpable(x, y, p)) && cOccupied::occupy(x, y, p))
break;
}
n--;
}
}
if (jumpable_warning)
info("Warning: Level contains impossible jumps!");
}
static void make_on_platform()
{
cRandomList on_platform(PLACEMENT_ON_PLATFORM);
if (on_platform.is_empty() || random_placement_on <= 0)
return;
for (cOccupied *o = game_occ; o != 0; o = (cOccupied *)o->next)
if (o->what->placement == PLACEMENT_PLATFORM)
for (int n = determine_number(random_placement_on); n > 0; n--)
{
cProperties *p = on_platform.get_weighted_random();
if (p->bbox.x2 - p->bbox.x1 >= o->x2 - o->x1
|| o->y2 < GAME_DY
|| o->y1 - p->bbox.y1 > LEVEL_SIZE)
continue;
for (int tries = 0; tries < MAX_TRIES; tries++)
{
int x = o->x1 - p->bbox.x1 + rnd(o->x2 - o->x1 - (p->bbox.x2 - p->bbox.x1)),
y = o->y1 + p->bbox.y2;
if (cOccupied::occupy(x, y, p))
break;
}
}
}
static void make_between_platforms()
{
}
static void make_under_platform()
{
cRandomList under_platform(PLACEMENT_UNDER_PLATFORM);
if (under_platform.is_empty() || random_placement_under <= 0)
return;
for (cOccupied *o = game_occ; o != 0; o = (cOccupied *)o->next)
if (o->what->placement == PLACEMENT_PLATFORM)
for (int n = determine_number(random_placement_under); n > 0; n--)
{
cProperties *p = under_platform.get_weighted_random();
if (p->bbox.x2 - p->bbox.x1 >= o->x2 - o->x1
|| o->y2 < GAME_DY
|| o->y1 - p->bbox.y1 > LEVEL_SIZE)
continue;
for (int tries = 0; tries < MAX_TRIES; tries++)
{
int x = o->x1 - p->bbox.x1 + rnd(o->x2 - o->x1 - (p->bbox.x2 - p->bbox.x1)),
y = o->y2 + p->bbox.y1;
if (cOccupied::occupy(x, y, p))
break;
}
}
}
static void make_any()
{
cRandomList any(PLACEMENT_ANY);
if (any.is_empty() || random_placement_any <= 0)
return;
for (int n = LEVEL_VLEVELS * random_placement_any / 100; n > 0; n--)
{
cProperties *p = any.get_weighted_random();
for (int tries = 0; tries < LEVEL_VLEVELS; tries++)
{
int x = -p->bbox.x1 + GAME_EDGE + rnd(GAME_DX - 2 * GAME_EDGE - (p->bbox.x2 - p->bbox.x1)),
y = GAME_DY + p->bbox.y2 + rnd((*p->objtype->surface)->total_h - GAME_DY - (p->bbox.y2 - p->bbox.y1));
if (cOccupied::occupy(x, y, p))
break;
}
}
}
void make_level()
{
// First create platforms and stuff between platforms
make_platforms();
make_between_platforms();
// Then create rest of shit
make_on_platform();
make_under_platform();
make_any();
// Remove occupied lists
back_occ->delete_list();
game_occ->delete_list();
// Create editables
cEditable::make_editables();
}